﻿using System.Text;
using Basic.FlowApplication.Extend;
using Basic.FlowApplication.Interface;
using Basic.FlowApplication.Model;
using Basic.FlowApplication.Model.AuditLog;
using Basic.FlowCollect;
using Basic.FlowModel.AuditState;
using Basic.FlowRemoteModel;
using Basic.FlowRemoteModel.Application.Model;
using WeDonekRpc.Client.Attr;
using WeDonekRpc.Helper;

namespace Basic.FlowApplication.AuditEvent
{
    /// <summary>
    /// 节点审批恢复
    /// </summary>
    [IocName("Audit_99")]
    [ClassLifetimeAttr(ClassLifetimeType.Scope)]
    internal class RestoreAuditEvent : IItemAuditEvent
    {
        private readonly IFlowAuditCopyLogCollect _CopyMsg;
        private readonly IFlowAuditNodeStateCollect _NodeState;
        public RestoreAuditEvent ( IFlowAuditCopyLogCollect copy,
            IFlowAuditNodeStateCollect nodeState )
        {
            this._NodeState = nodeState;
            this._CopyMsg = copy;
        }
        public AfootAuditLogItem ItemAudit ( AuditFlowBody flow, FlowAuditLogState log, AuditRes result )
        {
            AfootAuditLogItem item = log.LogItem.Find(a => a.Id == result.ItemId);
            item.CheckAuditItem(result);
            item.AuditState = FlowAuditItemStatus.审核通过;
            item.AuditOpinion = result.Opinion;
            item.SignFileId = result.SignFileId;
            this._Restore(flow, log, item, result.Restore);
            item.SubFlowState = FlowSubAuditStatus.审核通过;
            return item;
        }
        private void _Restore ( AuditFlowBody flow, FlowAuditLogState log, AfootAuditLogItem item, ChioseAuditNode restore )
        {
            if ( !item.OptItemId.HasValue || item.MarkState != FlowItemMarkState.退回 )
            {
                throw new ErrorException("flow.audit.not.allow.restore");
            }
            AfootAuditLogItem sour = log.LogItem.Find(a => a.Id == item.OptItemId.Value);
            FlowNode node = flow.Nodes[sour.NodeId];
            log.LogItem.Add(new AfootAuditLogItem(sour, LogItemChangeType.Add)
            {
                OptItemId = item.Id,
                CopyId = restore.CopyEmpId,
                TimeOut = node.LimitTime.HasValue ? DateTime.Now.AddMinutes(node.LimitTime.Value) : null
            });
            List<AfootAuditLogItem> list = log.LogItem.FindAll(c => c.OptItemId == sour.Id && c.Id != item.Id);
            if ( list.Count > 0 )
            {
                long[] ids = list.Convert(a => a.AuditState == FlowAuditItemStatus.审核进行中 || a.AuditState == FlowAuditItemStatus.待开始, a => a.Id);
                if ( !ids.IsNull() )
                {
                    Dictionary<long, long[]> copyEmp = this._CopyMsg.GetToEmpId(ids, FlowMsgType.审核通过);
                    list.ForEach(c =>
                    {
                        if ( c.AuditState == FlowAuditItemStatus.审核通过 && c.SubFlowState == FlowSubAuditStatus.已作废 )
                        {
                            AfootAuditLogItem set = c.Copy();
                            log.LogItem.Add(set);
                        }
                        else if ( c.Status == FlowAuditItemStatus.已作废 )
                        {
                            FlowNode cur = flow.Nodes[c.NodeId];
                            AfootAuditLogItem set = c.Copy();
                            set.OptItemId = item.Id;
                            set.CopyId = copyEmp.GetValueOrDefault(c.Id);
                            set.TimeOut = cur.LimitTime.HasValue ? DateTime.Now.AddMinutes(cur.LimitTime.Value) : null;
                            log.LogItem.Add(set);
                        }
                    });
                }
            }
            RestoreNodeState[] state = this._NodeState.GetRestoreNode(log.Id, item.OptItemId.Value);
            if ( !state.IsNull() )
            {
                state.ForEach(c =>
                {
                    if ( c.NodeId != item.NodeId )
                    {
                        log.SetNodeState(c.NodeId, c.PrevStatus.Value, item.Id);
                    }
                });
            }
            log.ProgressVal = log.CurNodeState.Where(a => a.Value == FlowNodeAuditStatus.审核通过).Select(a => flow.Nodes[a.Key].ProgressVal.GetValueOrDefault()).Max();
        }

    }
}
